using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Media.Imaging;
using Legacy.Core.SaveGameManagement;

namespace MMXSaveGameConverter
{
    internal sealed class SavFileReader : FileReaderBase
    {
        private readonly string _savPath;

        public SavFileReader(string savPath)
        {
            _savPath = savPath;
        }

        public override IReaderState Read()
        {
            return new SavReadState(_savPath);
        }

        public override SaveFileMeta ReadFileMeta(IReaderState readerState)
        {
            return new SaveFileMeta(Path.GetFileNameWithoutExtension(_savPath));
        }

        public override SaveGameMeta ReadSaveMeta(IReaderState readerState)
        {
            SavReadState state = (SavReadState)readerState;
            if (state.SaveMetaReaded)
                throw new InvalidOperationException();

            state.SaveMetaReaded = true;
            BinaryReader br = new BinaryReader(state.SavInput, Encoding.Default);
            return SaveGame.ReadMetaData(br);
        }

        public override SaveGame ReadSaveGame(IReaderState readerState, SaveGameMeta saveMeta)
        {
            SavReadState state = (SavReadState)readerState;
            if (!state.SaveMetaReaded || state.SaveGameReaded)
                throw new InvalidOperationException();

            state.SaveGameReaded = true;

            BinaryReader br = new BinaryReader(state.SavInput, Encoding.Default);
            SaveGame result = new SaveGame(saveMeta);

            int num = br.ReadInt32();
            for (int index = 0; index < num; index++)
            {
                string str = br.ReadString();
                SaveGameData saveGameData = new SaveGameData(str);
                saveGameData.Read(br);
                result.Add(saveGameData);
            }

            return result;
        }

        public override BitmapFrame ReadScreenshot(IReaderState readerState)
        {
            SavReadState state = (SavReadState)readerState;
            if (!state.SaveMetaReaded || !state.SaveGameReaded || state.ScreenshotReaded)
                throw new InvalidOperationException();

            state.ScreenshotReaded = true;

            BinaryReader br = new BinaryReader(state.SavInput, Encoding.Default);
            {
                int length = br.ReadInt32();
                using (StreamSegment segment = new StreamSegment(br.BaseStream, br.BaseStream.Position, length))
                {
                    PngBitmapDecoder decoder = new PngBitmapDecoder(segment, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.OnLoad);
                    return decoder.Frames.First();
                }
            }
        }
    }
}